import constants as const
from datacenter import datacenter as dc
from datacenter import CardData

class Card:
    """扑克牌类
    
    负责扑克牌的图形渲染和交互逻辑，包括绘制、移动、翻转和选择等功能。
    
    Attributes:
        canvas: Tkinter画布对象，用于绘制扑克牌
        data: 扑克牌数据对象，包含牌的基本信息
        width: 扑克牌宽度
        height: 扑克牌高度
        is_selected: 是否被选中
        is_face_up: 是否正面朝上
        is_show: 是否显示在画布上
    """
    def __init__(self, canvas, data: CardData):
        """初始化扑克牌对象
        
        Args:
            canvas: Tkinter画布对象
            data: 扑克牌数据对象
        """
        self.canvas = canvas
        self.data = data

        self.width = const.card_width
        self.height = const.card_height
        self.font_size = 14
        self.rb_font_size = 10
        self.corner_offset = [18, 15]
        self.text_color = self.get_color()
        self.is_selected = False  # 是否被选中

        self.is_face_up = True
        self.tags = ''
        self.is_show = False

        # 创建扑克牌的图形元素
        self.draw_card()

    def get_color(self):
        return 'red' if self.data.suit(True) in ['♥', '♦'] else 'black'

    def get_tag(self):
        """获取扑克牌的标签
        
        Returns:
            str: 扑克牌的唯一标签
        """
        return self.tags

    def draw_card(self):
        """绘制扑克牌
        
        根据扑克牌的朝向(正面/背面)绘制对应的图形
        """

        if self.tags != '':
            self.clear_graphics()
        
        self.tags = f"{self.data.layerid}-{self.data.index}"
        
        if self.is_face_up:
            self._draw_front()
        else:
            self._draw_back()

        self.is_show = True
    def _draw_front(self):
        """绘制扑克牌正面
        
        绘制包括背景、点数、花色和层级信息，并考虑旋转角度
        """
        x = self.data.x
        y = self.data.y
        rotation = self.data.rotation  # 获取旋转角度

        tags = self.get_tag()
        self.text_color = self.get_color()
        
        # 计算卡片中心点坐标
        center_x = x + self.width / 2
        center_y = y + self.height / 2

        # 绘制背景矩形
        self.rect = self.canvas.create_rectangle(
            x, y, x + self.width, y + self.height,
            fill='white', outline='black', tags=tags
        )

        # 左上角文字
        self.top_text = self.canvas.create_text(
            x + self.corner_offset[0], y + self.corner_offset[1],
            text=f"{self.data.card_str()}", fill=self.text_color, font=('Arial', self.font_size), tags=tags
        )

        # 中间花色符号
        suit = self.data.suit(True)
        brief = dc.get_ruleBrief(suit)
        
        self.center_suit = self.canvas.create_text(
            x + self.width // 2, y + self.height // 2,
            text=f"{brief}", fill=self.text_color, font=('Arial', self.font_size * 2), tags=tags
        )

        # 右下角层级
        self.right_text = self.canvas.create_text(
            x + self.width - self.corner_offset[0], y + self.height - self.corner_offset[1],
            text=f"{tags}", fill=self.text_color, font=('Arial', self.rb_font_size), tags=tags
        )
        
        # 如果有旋转角度，应用旋转变换
        if rotation != 0:
            # 对所有元素应用旋转变换
            items = [self.rect, self.top_text, self.center_suit, self.right_text]
            for item in items:
                # 使用rotate方法围绕卡片中心旋转
                self._rotate_item(item, center_x, center_y, rotation)

        if self.is_selected:
            self.select()


    def _draw_back(self):
        """绘制扑克牌背面
        
        绘制灰色背景表示牌的背面，并考虑旋转角度
        """
        x = self.data.x
        y = self.data.y
        rotation = self.data.rotation  # 获取旋转角度
        tags = self.get_tag()
        
        # 计算卡片中心点坐标
        center_x = x + self.width / 2
        center_y = y + self.height / 2

        # 绘制背景矩形
        self.rect = self.canvas.create_rectangle(
            x, y, x + self.width, y + self.height,
            fill='gray', outline='black', tags=tags
        )
        
        # 如果有旋转角度，应用旋转变换
        if rotation != 0:
            self._rotate_item(self.rect, center_x, center_y, rotation)

    def clear_graphics(self):
        """清除所有图形元素
        
        从画布上删除与当前扑克牌相关的所有图形元素
        """
        self.canvas.delete(self.get_tag())
        self.is_show = False
    
    def flip(self):
        """翻转扑克牌（切换正面/背面）
        
        切换扑克牌的正反面状态并重新绘制，保持旋转角度不变
        """
        self.is_face_up = not self.is_face_up
        self.draw_card()  # 重新绘制
    def move(self, dx, dy):
        """移动扑克牌
        
        Args:
            dx: x方向移动距离
            dy: y方向移动距离
        """
        self.canvas.move(self.get_tag(), dx, dy)
        self.data.x += dx
        self.data.y += dy

    def toggle_selection(self):
        """切换选中状态
        
        在选中和未选中状态之间切换
        """
        if self.is_selected:
            self.deselect()
        else:
            self.select()

    def select(self):
        """选中扑克牌
        
        将扑克牌标记为选中状态，并高亮显示边框
        """
        self.is_selected = True
        self.canvas.itemconfig(self.rect, outline=const.select_color, width=3)  # 高亮边框

    def deselect(self):
        """取消选中扑克牌
        
        将扑克牌标记为未选中状态，并恢复默认边框
        """
        self.is_selected = False
        self.canvas.itemconfig(self.rect, outline='black', width=1)  # 恢复默认边框
        
    def _rotate_item(self, item, center_x, center_y, angle):
        """旋转画布上的元素
        
        使用三角函数计算旋转后的坐标，然后重新设置元素位置
        对于文本元素，还需要设置其角度属性
        
        Args:
            item: 要旋转的画布元素
            center_x: 旋转中心x坐标
            center_y: 旋转中心y坐标
            angle: 旋转角度（度）
        """
        import math
        
        # 将角度转换为弧度
        angle_rad = math.radians(angle)
        cos_val = math.cos(angle_rad)
        sin_val = math.sin(angle_rad)
        
        # 获取元素类型
        item_type = self.canvas.type(item)
        
        if item_type == 'rectangle':
            # 获取矩形的四个角坐标
            x1, y1, x2, y2 = self.canvas.coords(item)
            
            # 计算四个角相对于中心点的偏移
            points = [(x1, y1), (x2, y1), (x2, y2), (x1, y2)]
            new_points = []
            
            # 计算旋转后的坐标
            for x, y in points:
                # 将坐标转换为相对于旋转中心的坐标
                dx = x - center_x
                dy = y - center_y
                
                # 应用旋转变换
                new_x = center_x + (dx * cos_val - dy * sin_val)
                new_y = center_y + (dx * sin_val + dy * cos_val)
                
                new_points.append((new_x, new_y))
            
            # 获取当前矩形的样式
            fill_color = self.canvas.itemcget(item, 'fill')
            outline_color = self.canvas.itemcget(item, 'outline')
            outline_width = self.canvas.itemcget(item, 'width')
            current_tags = self.canvas.gettags(item)
            
            # 删除原矩形
            self.canvas.delete(item)
            
            # 创建新的多边形替代矩形
            flat_points = [coord for point in new_points for coord in point]
            new_item = self.canvas.create_polygon(
                *flat_points,
                fill=fill_color,
                outline=outline_color,
                width=outline_width,
                tags=current_tags
            )
            
            # 如果旋转的是卡片的矩形背景，更新self.rect引用
            if item == self.rect:
                self.rect = new_item
            
        elif item_type == 'text':
            # 获取文本的锚点坐标
            x, y = self.canvas.coords(item)
            
            # 将坐标转换为相对于旋转中心的坐标
            dx = x - center_x
            dy = y - center_y
            
            # 应用旋转变换
            new_x = center_x + (dx * cos_val - dy * sin_val)
            new_y = center_y + (dx * sin_val + dy * cos_val)
            
            # 更新文本坐标
            self.canvas.coords(item, new_x, new_y)
            
            # 获取当前文本内容和样式
            current_text = self.canvas.itemcget(item, 'text')
            current_font = self.canvas.itemcget(item, 'font')
            current_fill = self.canvas.itemcget(item, 'fill')
            current_tags = self.canvas.gettags(item)
            
            # 删除原文本并创建新的旋转文本
            self.canvas.delete(item)
            new_item = self.canvas.create_text(
                new_x, new_y,
                text=current_text,
                fill=current_fill,
                font=current_font,
                tags=current_tags,
                angle=-angle  # 设置旋转角度
            )
